package cn.pconline.autoclub.service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.gelivable.auth.entity.GeliSession;
import org.gelivable.auth.entity.GeliUser;
import org.gelivable.dao.GeliDao;
import org.gelivable.dao.GeliOrm;
import org.gelivable.dao.SqlBuilder;
import org.gelivable.dao.SqlPageBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;

import cn.pconline.autoclub.entity.MessageDetail;
import cn.pconline.autoclub.entity.SendMsg;
import cn.pconline.autoclub.entity.User;
import cn.pconline.autoclub.util.DateUtils;
import cn.pconline.autoclub.util.Pager;
import cn.pconline.autoclub.util.club.ComboCnd;

/**
 *
 * @author chensy
 */
public class SendMsgService {

    @Autowired
    private GeliDao geliDao;
    @Autowired
    private GeliOrm geliOrm;
    @Autowired
    private PagerService pagerService;
    @Autowired
    private UserService userService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private SqlPageBuilder pageBuilder;

    /**
     * 根据ID获取信息数据（不走缓存）
     *
     * @param msgId
     * @return
     */
    public SendMsg findMsgFromDb(long msgId) {
        if (msgId <= 0) {
            return null;
        }
        try {
            return geliDao.findDb(SendMsg.class, msgId);
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }

    /**
     * （不走缓存）
     *
     * @param msgDetailId
     * @return
     */
    public MessageDetail findDetailFromDb(long msgDetailId) {
        try {
            return geliDao.findDb(MessageDetail.class, msgDetailId);
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }

    public int updateStatus(SendMsg msg, int status) {
        if (msg == null || status <= 0) {
            return 0;
        }
        msg.setStatus(status);
        msg.setUpdateAt(new Date());
        GeliUser u = GeliSession.getCurrentUser();
        if (u != null) {
            msg.setUpdateBy(u.getUserId());
        }
        return geliDao.update(msg, "status,update_at,update_by");
    }

    /**
     * 信息分页（仅系统消息类型）
     *
     * @param messageId
     * @param msg
     * @param beginDate
     * @param endDate
     * @param createBy
     * @param orderBy
     * @param pageNo
     * @param pageSize
     * @return
     */
    public Pager<SendMsg> pageForMsg(long messageId, String msg, String beginDate, String endDate, String createBy, String orderBy, int pageNo, int pageSize) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select * from ").appendSql(geliOrm.getTableName(SendMsg.class));
        sql.appendSql(" where type = ").appendValue(SendMsg.TYPE_SYS).appendSql(" and status != ").appendValue(SendMsg.STATUS_DELETE);
        if (messageId != 0) {
            sql.appendSql(" and  message_id=").appendValue(messageId);
        }
        if (StringUtils.isNotBlank(msg)) {
            sql.appendSql(" and content like ").appendValue("%" + msg + "%");
        }
        if (StringUtils.isNotBlank(beginDate) && StringUtils.isNotBlank(endDate)) {
            sql.appendSql(" and send_at >=").appendValue(beginDate).appendSql(" and send_at <=").appendValue(endDate);
        }
        if (StringUtils.isNotBlank(createBy)) {
            sql.appendSql(" and create_by=").appendValue(createBy);
        }
        if (StringUtils.isNotBlank(orderBy)) {
            sql.appendSql(" order by ").appendSql(orderBy).appendSql(" desc");
        }
        return pagerService.pager(SendMsg.class, sql, pageNo, pageSize);
    }
    
    /**
     * 给车友会全体成员发送车友会勋章系统消息
     * 
     * @param clubId
     */
    public void createClubMedalSysMsg(long sendBy, long clubId, String msgContent) {
    	List<User> list = userService.findAllUser(clubId, 0L);
        if (list == null || list.isEmpty()) {
        	return;
        }
    	
    	SendMsg message = new SendMsg();
    	message.setCreateAt(DateUtils.getNow());
    	message.setSendAt(DateUtils.getNow());
    	message.setCreateBy(sendBy);
    	message.setContent(msgContent);
    	message.setSendAll(SendMsg.SCOPE_ALL_USER);
    	message.setStatus(SendMsg.SEND_SETOUT);
        message.setType(SendMsg.TYPE_SYS);
        message.setSendNum(list.size());
        message.setLessNum(list.size());
        
        //生成发送名单
        geliDao.create(message);
        this.setSendList(message.getMsgId(), list);
    }

    /**
     * 发车友会动态消息
     *
     * @param sendBy
     * @param clubId
     * @param jsonContent
     */
    public void createClubDynaMsg(long sendBy, long clubId, String jsonContent) {
        SendMsg message = new SendMsg();
        message.setCreateAt(DateUtils.getNow());
        message.setCreateBy(sendBy);
        message.setContent(jsonContent);
        message.setSendAt(new Date());
        message.setSendAll(SendMsg.SCOPE_CLUB_MEMBER);
        message.setStatus(SendMsg.SEND_SETOUT);
        message.setType(SendMsg.TYPE_CLUB_DYNA);
        //把自己排除，不会发给自己
        List<User> list = userService.findAllUser(clubId, sendBy);
        if (list.isEmpty()) {
            //没有发送对象时不需要插入
            return;
        }
        message.setSendNum(list.size());
        message.setLessNum(list.size());
        //生成发送名单
        geliDao.create(message);
        this.setSendList(message.getMsgId(), list);
    }

    /**
     * 添加
     *
     * @param msgId
     * @param content
     * @param sendAt
     * @param scope 0:不是全部 ，1：全部
     * @param adminId
     * @param comboCnd 地区与品牌选择条件组合
     * @return 如果没有满足条件的人员，则返回false
     */
    public boolean createSystemMsg(String content, Date sendAt,
            int scope, long adminId, String comboCnd) {
        final SendMsg message = new SendMsg();
        message.setCreateAt(DateUtils.getNow());
        message.setCreateBy(adminId);
        message.setContent(content);
        message.setSendAt(sendAt);
        message.setSendAll(scope);
        message.setStatus(SendMsg.SEND_BEIN);
        message.setType(SendMsg.TYPE_SYS);
        message.setComboCnd(comboCnd);
        List<ComboCnd> cnds = SendMsg.getComboCndList(comboCnd);
        final List<User> list = userService.findClubUser(scope, null, cnds);
        if (list.isEmpty()) {
            return false;
        }
        message.setSendNum(list.size());
        message.setLessNum(list.size());
        message.setCreateStatus(SendMsg.CREATE_STATUS_UNDO);
        //生成发送名单
        geliDao.create(message);
        new Thread(new Runnable() {
            @Override
            public void run() {
                message.setCreateStatus(SendMsg.CREATE_STATUS_DOING);
                geliDao.update(message, "create_status");
                setSendList(message.getMsgId(), list);
                message.setCreateStatus(SendMsg.CREATE_STATUS_DONE);
                geliDao.update(message, "create_status");
            }
        }).start();
        return true;
    }

    /**
     * 生成消息发送名单
     *
     * @param msgId
     * @param pager
     */
    public void setSendList(long msgId, List<User> list) {
        StringBuilder sql = new StringBuilder();
        sql.append("INSERT INTO  ");
        sql.append(geliOrm.getTableName(MessageDetail.class));
        sql.append(" (message_detail_id, message_id, user_name, user_id, status, create_at) value (?, ?, ?, ?, ?, ?)");

        List<Object[]> batchArgs = new ArrayList<Object[]>();
        for (User user : list) {
            /*
             MessageDetail msgDetail = new MessageDetail();
             msgDetail.setUserName(user.getUsername());
             msgDetail.setUid(user.getUid());
             msgDetail.setStatus(MessageDetail.SEND_NO);
             msgDetail.setCreateAt(DateUtils.getNow());
             msgDetail.setMessageId(msgId);
             geliDao.create(msgDetail);
             */
            List<Object> params = new ArrayList<Object>();
            params.add(geliDao.generateId(MessageDetail.class));
            params.add(msgId);
            params.add(user.getUsername());
            params.add(user.getUid());
            params.add(MessageDetail.SEND_NO);
            params.add(DateUtils.getNow());
            batchArgs.add(params.toArray());
        }
        geliDao.getJdbcTemplate().batchUpdate(sql.toString(), batchArgs);
    }

    /**
     * 根据消息ID删除发送信息
     *
     * @param activityId
     * @return
     */
    public int removeSengListByMsgId(long msgId) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql(" delete from ").appendSql(geliOrm.getTableName(MessageDetail.class));
        sql.appendSql(" where message_id = ? ");
        return jdbcTemplate.update(sql.getSql(), msgId);
    }

    /**
     * 消息详情分页方法
     *
     * @param msgId
     * @param orderField
     * @param pageNo
     * @param pageSize
     * @return
     */
    public Pager<MessageDetail> pageForMsgDetail(long msgId, Integer status, String orderField, String orderDirection,
            int pageNo, int pageSize) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql(" select * from ").appendSql(geliOrm.getTableName(MessageDetail.class)).appendSql(" where 1=1 ");
        if (msgId > 0) {
            sql.appendSql(" and message_id = ").appendValue(msgId);
        }
        if (status != null) {
            sql.appendSql(" and status = ").appendValue(status);
        }
        if (StringUtils.isNotBlank(orderField)) {
            sql.appendSql(" order by " + orderField + " " + orderDirection);
        }
        Pager<MessageDetail> pager = pagerService.pagerWithOutList(MessageDetail.class, sql, pageNo, pageSize);
        if (pager.getTotal() <= 0) {
            pager.setResultList(new ArrayList());
            return pager;
        }
        String pageSql = pageBuilder.buildPageSql(sql.getSql(), pageNo, pageSize);
        List<MessageDetail> list = jdbcTemplate.query(pageSql, sql.getValues(), new ResultSetExtractor<List<MessageDetail>>() {
            @Override
            public List<MessageDetail> extractData(ResultSet rs) throws SQLException, DataAccessException {
                List<MessageDetail> list = new ArrayList<MessageDetail>();
                while (rs.next()) {
                    MessageDetail m = new MessageDetail();
                    m.setMessageDetailId(rs.getLong("message_detail_id"));
                    m.setMessageId(rs.getLong("message_id"));
                    m.setUserName(rs.getString("user_name"));
                    m.setUid(rs.getLong("user_id"));
                    m.setStatus(rs.getInt("status"));
                    m.setCreateAt(rs.getDate("create_at"));
                    m.setSendAt(rs.getDate("send_at"));
                    list.add(m);
                }
                return list;
            }
        });
        pager.setResultList(list);
        return pager;
    }

    /**
     * 根据信息ID删除信息和详细信息
     *
     * @param msgId
     */
    public void remove(SendMsg msg, long msgId) {
        geliDao.delete(msg, msgId);
        this.removeSengListByMsgId(msgId);
    }
}
